/**
 * http://www.koorz.com
 * Copyright (c) 2012 shanghai meiku information technology co,.ltd
 */
package com.koorz.utils;

import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;

import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Record;
import com.koorz.modules.user.User;

/**
 * 功能描述：登录退出回话上下文 作 者：尹东东 创建时间：2013-5-21 下午5:36:37 版 本 号：1.0
 */
public class SessionContext {
	private final static ThreadLocal<SessionContext> contexts = new ThreadLocal<SessionContext>();
	private HttpServletRequest request;
	private HttpServletResponse response;
	private Map<String, Cookie> cookies;

	/**
	 * 
	 * 功能描述：初始化回话上下文 作 者：尹东东 创建时间：2013-5-21 下午5:58:27 参 数:req 返 回:无 异 常：无 版 本
	 * 号：1.0
	 */
	public static SessionContext init(HttpServletRequest req,
			HttpServletResponse resp) {
		SessionContext sc = new SessionContext();
		sc.request = req;
		sc.response = resp;
		sc.cookies = new HashMap<String, Cookie>();
		Cookie[] cookies = req.getCookies();
		if (cookies != null)
			for (Cookie ck : cookies) {
				sc.cookies.put(ck.getName(), ck);
			}
		contexts.set(sc);
		return sc;
	}

	/**
	 * 
	 * 功能描述：获取当前请求的上下文 作 者：尹东东 创建时间：2013-5-21 下午6:00:19 返 回:SessionContext 异 常：无
	 * 版 本 号：1.0
	 */
	public static SessionContext get() {
		return contexts.get();
	}
	
	public HttpServletRequest getRequest() {
		return request;
	}

	public HttpServletResponse getResponse() {
		return response;
	}

	public String ip() {
		return RequestUtils.getRemoteAddr(request);
	}

	public Cookie cookie(String name) {
		return cookies.get(name);
	}

	public void cookie(String name, String value, int max_age,
			boolean all_sub_domain) {
		RequestUtils.setCookie(request, response, name, value, max_age,
				all_sub_domain);
	}

	public void deleteCookie(String name, boolean all_domain) {
		RequestUtils.deleteCookie(request, response, name, all_domain);
	}

	public String header(String name) {
		return request.getHeader(name);
	}

	/**
	 * 
	 * 功能描述：获取当前登录用户信息 
	 * 作 者：尹东东 
	 * 创建时间：2013-5-21 下午6:07:05
	 * 参 数: 
	 * 返 回:User 
	 * 异 常：无 
	 * 版 本号：1.0
	 */
	public User user() {
		User loginUser = (User)request.getAttribute(CURRENT_LOGIN_USER);
		if(loginUser == null){
			//从Cookie中解析出用户id
			User cookieUser = SessionContext.get().getUserFromCookie();
			if(cookieUser == null) return null;
			User user = User.dao.findFirst("select * from user where id=? and type=?", cookieUser.getStr("id"),cookieUser.getInt("type"));
			if(user != null) {
				updateUser(user);
				return user;
			}
		}
		return loginUser;
	}

	/**
	 * 
	 * 功能描述：更新当前登录用户信息
	 * 作        者：尹东东
	 * 创建时间：2013-5-22 上午11:10:16
	 * 参       数:
	 * 返       回:无
	 * 异       常：无
	 * 版  本 号：1.0
	 */
	public void updateUser(User user){
		//获取用户最后一次登录时间
		String ip = ip();
		Record loginHistory = Db.findFirst("select * from login_history where user_id=? and ip=? order by login_time desc", user.getStr("id"),ip);
		boolean isToday = (loginHistory==null)?false:DateUtil.isToday(loginHistory.getTimestamp("login_time"));
		
		//超过半个小时
		if(user.getInt("online") != 1 || !isToday || (System.currentTimeMillis()-loginHistory.getTimestamp("login_time").getTime())>3600000){
			User.settingOnline(user.getStr("id"), ip);
		}
		request.setAttribute(CURRENT_LOGIN_USER, user);
	}
	
	public void saveUserInCookie(User user, boolean save) {
		String new_value = genLoginKey(user, ip(), header("user-agent"));
		int max_age = save ? MAX_AGE : -1;
		deleteCookie(COOKIE_LOGIN, true);
		cookie(COOKIE_LOGIN, new_value, max_age, true);
	}

	public void deleteUserInCookie() {
		deleteCookie(COOKIE_LOGIN, true);
	}

	/**
	 * 
	 * 功能描述：生成用户登录标识字符串 作 者：尹东东 创建时间：2013-5-21 下午6:23:51 参 数: 返 回:无 异 常：无 版 本
	 * 号：1.0
	 */
	public static String genLoginKey(User user, String ip, String userAgent) {
		StringBuilder sb = new StringBuilder();
		sb.append(user.getStr("id"));
		sb.append('|');
		sb.append(user.getInt("type"));
		sb.append('|');
		sb.append(ip);
		sb.append('|');
		sb.append((userAgent == null) ? 0 : userAgent.hashCode());
		sb.append('|');
		sb.append(System.currentTimeMillis());
		return CryptUtils.encrypt(sb.toString());
	}

	/**
	 * 从cookie中读取保存的用户信息
	 * 
	 * @param req
	 * @return
	 */
	public User getUserFromCookie() {
		try {
			Cookie cookie = cookie(COOKIE_LOGIN);
			if (cookie != null && StringUtils.isNotBlank(cookie.getValue())) {
				return userFromUUID(cookie.getValue());
			}
		} catch (Exception e) {
		}
		return null;
	}

	/**
	 * 从cookie中读取保存的用户信息
	 * 
	 * @param req
	 * @return
	 */
	public User userFromUUID(String uuid) {
		if (StringUtils.isBlank(uuid))
			return null;
		String ck = CryptUtils.decrypt(uuid);
		final String[] items = StringUtils.split(ck, '|');
		if (items.length == 5) {
			String ua = header("user-agent");
			int ua_code = (ua == null) ? 0 : ua.hashCode();
			int old_ua_code = Integer.parseInt(items[3]);
			if (ua_code == old_ua_code) {
				return new User().set("id", items[0]).set("type", Integer.parseInt(items[1]));
			}
		}
		return null;
	}

	private final static String CURRENT_LOGIN_USER = "onlineUser";
	public final static String COOKIE_LOGIN = "cookie_koorz_id";
	private final static int MAX_AGE = 86400 * 365;
}
